/**
 * 
 */
package org.dbp.core.service.dao.impl;

import java.io.Serializable;
import java.util.List;

import javax.sql.DataSource;

import org.dbp.core.service.core.GenericPrepared;
import org.dbp.core.service.core.TipoPrepared;
import org.dbp.core.service.core.utils.SqlUtils;
import org.dbp.core.service.dao.GenericDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

/**
 * @author dbp
 *
 */
public class GenericDaoImpl 
	<C extends Serializable,ID extends Serializable,FL extends Serializable> 
		implements GenericDao<C,ID,FL>{

	private RowMapper<C> rowMapper;
	private GenericPrepared<C> preparedStatementSetter; 
	private GenericPrepared<FL> preparedFilter;
	private String tabla;
	
	private JdbcTemplate jdbcTemplate;

	@SuppressWarnings("unused")
	private Class<C> claseC;
	private Class<ID> claseID;
	private String campoId;
	@Autowired
	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}
	
	public GenericDaoImpl(GenericPrepared<FL> preparedFilter,GenericPrepared<C> preparedStatementSetter,RowMapper<C> rowMapper,Class<C> claseC,String campoId) {
		super();
		this.preparedStatementSetter=preparedStatementSetter;
		this.rowMapper = rowMapper;
		this.claseC=claseC;
		this.tabla=claseC.getSimpleName();
		this.campoId=campoId;
		this.preparedFilter=preparedFilter;

	}

	
	public ID insert(C obj) {
		this.preparedStatementSetter.setEntity(obj);
		this.preparedStatementSetter.setTipoPrepared(TipoPrepared.INSERT);
		this.jdbcTemplate.update(SqlUtils.generateInsert(this.preparedStatementSetter.getCampos(), tabla),this.preparedStatementSetter);
		return this.jdbcTemplate.queryForObject("select last_insert_id()", claseID);
	}

	
	public C findId(ID id) {
		return this.jdbcTemplate.queryForObject(SqlUtils.generarFindId(tabla, campoId),new Object[]{id},rowMapper);
	}

	
	public List<C> findAll() {
		return this.jdbcTemplate.query(SqlUtils.generarFindAll(tabla),rowMapper);
	}

	
	public List<C> findFilter(FL filtro) throws Exception{
		this.preparedFilter.setEntity(filtro);
		return this.jdbcTemplate.query(
				SqlUtils.generarConsultaFiltro(tabla,filtro)
				,this.preparedFilter,rowMapper
				);
	}
	
	
	public C update(C obj) {
		this.preparedStatementSetter.setEntity(obj);
		this.preparedStatementSetter.setTipoPrepared(TipoPrepared.UPDATE);
		this.jdbcTemplate.update(SqlUtils.generarUpdate(tabla,campoId,this.preparedStatementSetter.getCampos()),this.preparedStatementSetter);
		return obj;
	}

	
	public C uptateNotNull(C obj) {
		return null;
	}

	
	public void remove(ID id) {
		this.jdbcTemplate.update(SqlUtils.generarDelete(tabla, campoId),new Object[]{id});
	}	
	
	
}